//Download by http://www.NewXing.com
// ToolTipWnd.cpp : implementation file
//

#include "stdafx.h"
#include "testdown.h"
#include "ToolTipWnd.h"
//#include "MemDC.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CToolTipWnd

CToolTipWnd::CToolTipWnd()
{
	//Registry Class
	m_lpWndCls=AfxRegisterWndClass(0);
	
	//Initial variable
	m_bMouseIn=false;
	m_iWidth=80;
	m_iHeight=14;
	m_clrBkColor=RGB(254,254,224);
	m_clrTextColor=RGB(0,0,0);
	m_clrFrameColor=RGB(0,0,255);
	m_iFontHeight=14;
	m_iFontWidth=0;
	m_strFontName="Times New Roman";
	//m_strFontName="System";
	m_pCurrwnd=NULL;
	m_iNumText=0;
	m_iNumTextComp=0;
	m_bIsPaint=FALSE;
	//m_bIsPaintHeight=FALSE;

}

CToolTipWnd::~CToolTipWnd()
{
	BTOOLINFO *stToolInfo;
	CWnd *pWnd;
	for(POSITION pos=m_ToolPtr.GetStartPosition();pos!=NULL;)
	{
		m_ToolPtr.GetNextAssoc(pos,(void*&)pWnd,(void*&)stToolInfo);
		delete stToolInfo;
	}

	m_ToolPtr.RemoveAll();
}


BEGIN_MESSAGE_MAP(CToolTipWnd, CWnd)
	//{{AFX_MSG_MAP(CToolTipWnd)
	ON_WM_PAINT()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CToolTipWnd message handlers
void CToolTipWnd::SetWidth(int iWidth)
{
	m_iWidth=iWidth;
}
void CToolTipWnd::SetHeight(int iHeight)
{
	m_iHeight=iHeight;
}
void CToolTipWnd::SetBkColor(COLORREF clrRef)
{
	m_clrBkColor=clrRef;
}
void CToolTipWnd::SetDefTextColor(COLORREF clrRef)
{
	m_clrTextColor=clrRef;
}
void CToolTipWnd::SetFrameColor(COLORREF clrRef)
{
	m_clrFrameColor=clrRef;
}
void CToolTipWnd::SetFontHeight(int iHeight)
{
	m_iFontHeight=iHeight;
}
void CToolTipWnd::SetFontName(CString strFontName)
{
	m_strFontName=strFontName;
}

BOOL CToolTipWnd::Create(CWnd *pParentWnd)
{
	BOOL bRet=CWnd::CreateEx(NULL,m_lpWndCls,NULL,WS_POPUP,
		        0,0,m_iWidth,m_iHeight,pParentWnd->GetSafeHwnd(),NULL,NULL);
	
	m_hParentWnd=pParentWnd->GetSafeHwnd();
	
	if(bRet)
		SetOwner(pParentWnd);

	return bRet;

}













void CToolTipWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	CRect rectCl;
	GetClientRect(&rectCl);
	CFont *pOldFont=dc.SelectObject(&m_FontText);
	CSize czTextWidth=dc.GetTextExtent(m_strExtentText);
	int x=0,y=0;
	if(m_bIsPaint)
	{
		m_bIsPaint=FALSE;
		x=0,y=0;
		if(m_iNumText!=m_iNumTextComp)
		{
			if(m_iNumText!=1)
				y=14/2;
			if(czTextWidth.cx>rectCl.Width())
			{
				x=((int)czTextWidth.cx-rectCl.Width())/2+20;
			}
			if(m_iNumText>m_iNumTextComp)
			{
				rectCl.DeflateRect(-x,-y);
				rectCl.OffsetRect(x,y);
			}
			else
			{
				rectCl.DeflateRect(-x,y);
				rectCl.OffsetRect(x,y);
			}
			m_iWidth=rectCl.Width();
			m_iHeight=rectCl.Height();
			m_iNumTextComp=m_iNumText;
			
			CRect nrect;
			nrect=rectCl;
			ClientToScreen(&nrect);
			SetWindowPos(&wndTop,nrect.left-x,nrect.top,m_iWidth,m_iHeight,SWP_NOACTIVATE);

			m_RectText.left=1;
			m_RectText.top=1;
			m_RectText.right=rectCl.Width();
			m_RectText.bottom=czTextWidth.cy*m_iNumText;

		


			m_rgn.m_hObject=NULL;
			m_rgnTri.m_hObject=NULL;
			m_rgnComb.m_hObject=NULL;

		//GetClientRect(&rectCl);

		//Create Elliptic Rgn
		//BOOL bRegRet=m_rgn.CreateEllipticRgn(rectCl.left+10,rectCl.top,rectCl.right,rectCl.bottom);
			BOOL bRegRet=m_rgn.CreateRectRgn(rectCl.left+0,rectCl.top,rectCl.right,rectCl.bottom);
	
			CPoint ptTri[3];
			ptTri[0].x=rectCl.left;
			ptTri[0].y=(rectCl.bottom/2)-5;
			ptTri[1].x=rectCl.left+5;
			ptTri[1].y=(rectCl.bottom/2)-0;
			ptTri[2].x=rectCl.left+5;
			ptTri[2].y=(rectCl.bottom/2)+0;

			BOOL bRegTriRet=m_rgnTri.CreatePolygonRgn(ptTri,3,ALTERNATE);

			m_rgnComb.CreateRectRgn(rectCl.left+0,rectCl.top,rectCl.right,rectCl.bottom);
			int iRetComb=m_rgnComb.CombineRgn(&m_rgnTri,&m_rgn,RGN_OR);
			if(iRetComb==ERROR)
			{
				MessageBox("Error in Combining Region","Leo",MB_OK|MB_ICONSTOP);
				return;
			}

			int bRgnWnd=SetWindowRgn(m_rgnComb.operator HRGN(),TRUE);
			//int bRgnWnd=SetWindowRgn(m_rgn.operator HRGN(),TRUE);

		}

	

		/*x=0,y=0;
		//GetClientRect(&rectCl);
		CRect rectTemp;
		rectTemp=rectCl;
		rectTemp.left=rectTemp.left+10;
		x=(int)((float)((float)rectTemp.Width()/2.0)/1.41421);
		y=(int)((float)((float)rectTemp.Height()/2.0)/1.41421);

		m_RectText.top=((rectTemp.Height()/2)-y);
		m_RectText.left=((rectTemp.Width()/2)-x)+10;
		m_RectText.right=((rectTemp.Width()/2)+x)+10;
		m_RectText.bottom=((rectTemp.Height()/2)+y);*/
		
		//m_RectText=rectCl;

	}

	//GetClientRect(&rectCl);


	//Create Comb CRgn;
	CRgn rgnComb;
	rgnComb.CreateRectRgn(rectCl.left+0,rectCl.top,rectCl.right,rectCl.bottom);
	
	//m_rgn or m_rgnTri in OnCreate()
	int iRetComb=rgnComb.CombineRgn(&m_rgnTri,&m_rgn,RGN_OR);
	if(iRetComb==ERROR)
	{
		MessageBox("Error in Combining Region","Leo",MB_OK|MB_ICONSTOP);
		return;
	}
	
	CBrush pBrush;
	pBrush.CreateSolidBrush(m_clrFrameColor);
	CBrush pBrush1;
	pBrush1.CreateSolidBrush(m_clrBkColor);
	
	dc.FillRgn(&rgnComb,&pBrush1);
	dc.FrameRgn(&rgnComb,&pBrush,2,1);
	//dc.FillRgn(&m_rgn,&pBrush1);
	//dc.FrameRgn(&m_rgn,&pBrush,2,1);

	dc.SetBkMode(TRANSPARENT);
	dc.SetTextColor(m_clrTextColor);
	//pOldFont=pDC->SelectObject(&m_FontText);

	//dc.DrawText(m_strText,m_RectText,DT_CENTER|DT_WORDBREAK);
	dc.DrawText(m_strText,m_RectText,DT_CENTER);

	dc.SelectObject(pOldFont);
	// Do not call CWnd::OnPaint() for painting messages
}

int CToolTipWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	CRect rectCl;
	GetClientRect(&rectCl);

	/*int x=0,y=0;
	CRect rectTemp;
	rectTemp=rectCl;
	rectTemp.left=rectTemp.left+0;
	x=(int)((float)((float)rectTemp.Width()/2.0)/1.41421);
	y=(int)((float)((float)rectTemp.Height()/2.0)/1.41421);*/

	//m_RectText.top=((rectTemp.Height()/2)-y);
	//m_RectText.left=((rectTemp.Width()/2)-x)+2;
	//m_RectText.right=((rectTemp.Width()/2)+x)+2;
	//m_RectText.bottom=((rectTemp.Height()/2)+y);
	m_RectText=rectCl;
	m_RectText.left=1;
	m_RectText.top=1;

	m_rgn.m_hObject=NULL;
	m_rgnTri.m_hObject=NULL;
	m_rgnComb.m_hObject=NULL;

	//Create Elliptic Rgn
	//BOOL bRegRet=m_rgn.CreateEllipticRgn(rectCl.left+10,rectCl.top,rectCl.right,rectCl.bottom);
	BOOL bRegRet=m_rgn.CreateRectRgn(rectCl.left+0,rectCl.top,rectCl.right,rectCl.bottom);
	
	CPoint ptTri[3];
	ptTri[0].x=rectCl.left;
	ptTri[0].y=(rectCl.bottom/2)-5;
	ptTri[1].x=rectCl.left+5;
	ptTri[1].y=(rectCl.bottom/2)-0;
	ptTri[2].x=rectCl.left+5;
	ptTri[2].y=(rectCl.bottom/2)+0;

	BOOL bRegTriRet=m_rgnTri.CreatePolygonRgn(ptTri,3,ALTERNATE);

	m_rgnComb.CreateRectRgn(rectCl.left+0,rectCl.top,rectCl.right,rectCl.bottom);
	int iRetComb=m_rgnComb.CombineRgn(&m_rgnTri,&m_rgn,RGN_OR);
	if(iRetComb==ERROR)
	{
		MessageBox("Error in Combining Region","Leo",MB_OK|MB_ICONSTOP);
		return -1;
	}

	int bRgnWnd=SetWindowRgn(m_rgnComb.operator HRGN(),TRUE);
	//int bRgnWnd=SetWindowRgn(m_rgn.operator HRGN(),TRUE);
	m_FontText.CreateFont(m_iFontHeight,m_iFontWidth,0,0,0,0,0,0,0,0,0,0,0,m_strFontName);
	
	return 0;
}

void CToolTipWnd::AddTool(CWnd *pWnd,CString strText,COLORREF clrTextColor)
{
	BTOOLINFO *stToolInfo;
	
	if(!m_ToolPtr.Lookup(pWnd,(void*&)stToolInfo))
	{
		//no Find 
		stToolInfo=new BTOOLINFO;
		stToolInfo->hwndTool=pWnd->GetSafeHwnd();
		stToolInfo->strToolText=strText;
		if(clrTextColor==NULL)
			stToolInfo->clrToolTextClr=m_clrTextColor;
		else
			stToolInfo->clrToolTextClr=clrTextColor;

		m_ToolPtr.SetAt(pWnd,stToolInfo);
	}
}

void CToolTipWnd::RelayEvent(LPMSG lpMsg)
{
	switch(lpMsg->message)
	{
	case WM_KEYDOWN:
		if(IsWindowVisible())
		{
			ShowWindow(SW_HIDE);
		}
		break;
	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
		if(IsWindowVisible())
		{
			ShowWindow(SW_HIDE);
		}
		break;
	case WM_NCMOUSEMOVE:
	case WM_MOUSEMOVE:
		{
			//CWnd *pFocusWnd=AfxGetApp()->m_pMainWnd->GetFocus();
			//if(pFocusWnd==NULL)
			//	break;
			//CPoint pt;
			//pt.x=lpMsg->pt.x;
			//pt.y=lpMsg->pt.y;
			
			CWnd *pWnd=CWnd::FromHandle(lpMsg->hwnd);
			CRect rCl;
			BTOOLINFO *stToolInfo;
			CWnd *pBToolWnd;
			UINT nFlag=(UINT)lpMsg->wParam;
			
			if(nFlag!=MK_LBUTTON)
			for(POSITION pos=m_ToolPtr.GetStartPosition();pos!=NULL;)
			{
				
				m_ToolPtr.GetNextAssoc(pos,(void*&)pBToolWnd,(void*&)stToolInfo);
				if(!m_bMouseIn)
				{
					if(lpMsg->hwnd==stToolInfo->hwndTool)
					{

						::GetWindowRect(stToolInfo->hwndTool,&m_ParentRect);
						GetClientRect(&rCl);
						m_bMouseIn=true;
						m_clrTextColor=stToolInfo->clrToolTextClr;
						m_strText=stToolInfo->strToolText;
						//ScreenToClient(&ptCl);
						SetWindowPos(&wndTop,m_ParentRect.left-rCl.Width()/3,m_ParentRect.top+35,m_iWidth,m_iHeight,SWP_NOACTIVATE);
						ShowWindow(SW_SHOWNOACTIVATE);

						m_pCurrwnd=stToolInfo->hwndTool;
						break;

					}
				}
				else
				{
					//CRect rect;
					//CPoint npt;
					//::GetWindowRect(m_pCurrwnd,&m_ParentRect);
					//::GetCursorPos(&npt);
					CWnd *WndPt=pWnd->WindowFromPoint(lpMsg->pt);

					if(WndPt->GetSafeHwnd()!=m_pCurrwnd)
					{

						m_bMouseIn=false;
						ShowWindow(SW_HIDE);
					}
					break;
				}

			}

		}
		break;

	}
}


void CToolTipWnd::UpdateText(int iNumText,CString strExtentText,CString strText,CWnd *pWnd,COLORREF clrTextColor)
{
	m_iNumText=iNumText;
	m_strExtentText=strExtentText;

	BTOOLINFO *stToolInfo;
	
	if(m_ToolPtr.Lookup(pWnd,(void*&)stToolInfo))
	{
		//Find delete
		delete stToolInfo;
		m_ToolPtr.RemoveKey(pWnd);
		
		//Add new Map
		stToolInfo=new BTOOLINFO;
		stToolInfo->hwndTool=pWnd->GetSafeHwnd();
		stToolInfo->strToolText=strText;
		if(clrTextColor==NULL)
			stToolInfo->clrToolTextClr=m_clrTextColor;
		else
			stToolInfo->clrToolTextClr=clrTextColor;

		m_ToolPtr.SetAt(pWnd,stToolInfo);
	}
	m_bIsPaint=TRUE;
	Invalidate();

}
